package com.glsc.ngateway.platform.config;


import com.glsc.ngateway.common.api.common.enums.RabbitExcQueConstant;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class RabbitMQConfig {
    //交换机声明---------------------------------------------------------
    //默认交换机
    @Bean("exchangeDefault")
    public TopicExchange exchangeDefault() {
        return ExchangeBuilder.topicExchange(RabbitExcQueConstant.AMPRODUCT_EXCHANGE_DEFAULT).durable(true).build();
    }

    //死信交换机
    @Bean("exchangeDead")
    public TopicExchange exchangeDead() {
        return ExchangeBuilder.topicExchange(RabbitExcQueConstant.AMPRODUCT_EXCHANGE_DEAD).durable(true).build();
    }

    //交换机声明---------------------------------------------------------
    //移动审批
    @Bean("exchangeOaMobileAudit")
    public DirectExchange exchangeOaMobileAudit() {
        return ExchangeBuilder.directExchange(RabbitExcQueConstant.GATEWAY_EXCHANGE_FLOW_OA_MOBILE_AUDIT).durable(true).build();
    }
    @Bean("exchangeCmdb")
    public DirectExchange exchangeCmdb() {
        return ExchangeBuilder.directExchange(RabbitExcQueConstant.GATEWAY_EXCHANGE_FLOW_CMDB).durable(true).build();
    }
    //交换机声明---------------------------------------------------------
    //itflow
    @Bean("exchangeItflow")
    public DirectExchange exchangeItflow() {
        return ExchangeBuilder.directExchange(RabbitExcQueConstant.GATEWAY_EXCHANGE_FLOW_ITFLOW).durable(true).build();
    }

    //网关flowable流程消息交换
    @Bean("exchangeFlowableMsg")
    public DirectExchange exchangeFlowableMsg() {
        return ExchangeBuilder.directExchange(RabbitExcQueConstant.EXCHANGE_EASY_FLOW_MSG).durable(true).build();
    }
    //End of 交换机声明---------------------------------------------------------


    //队列声明---------------------------------------------------------
    //声明死信队列
    @Bean("queueForDead")
    public Queue queueForDead() {
        return new Queue(RabbitExcQueConstant.AMPRODUCT_QUEUE_DEAD);
    }


    //声明队列（短信邮件消息）
    @Bean("queueForMessage")
    public Queue queueForMessage() {
        //获取默认死信队列默认参数
//        Map<String, Object> args = this.getDefaultDeadQueueArgs();
        return QueueBuilder.durable(RabbitExcQueConstant.AMPRODUCT_QUEUE_MESSAGE).build();
    }

    //声明队列（异步任务）
    @Bean("queueForTask")
    public Queue queueForTask() {
        //获取默认死信队列默认参数
//        Map<String, Object> args = this.getDefaultDeadQueueArgs();
        return QueueBuilder.nonDurable(RabbitExcQueConstant.AMPRODUCT_QUEUE_TASK).build();
    }

    //声明队列（工作流程通知队列）
    @Bean("queueForWorkflow")
    public Queue queueForWorkflow() {
        //获取默认死信队列默认参数，【重要】 OA建立的通知队列，不包括死信队列
//        Map<String, Object> args = this.getDefaultDeadQueueArgs();
        return QueueBuilder.durable(RabbitExcQueConstant.AMPRODUCT_QUEUE_WORKFLOW).build();
    }

    //声明队列（OA流程状态变更通知队列）
    @Bean("queueForOaWorkflowRemind")
    public Queue queueForOaWorkflowRemind() {
        //获取默认死信队列默认参数，【重要】 OA建立的通知队列，不包括死信队列
//        Map<String, Object> args = this.getDefaultDeadQueueArgs();
        return QueueBuilder.durable(RabbitExcQueConstant.AMPRODUCT_QUEUE_OA_WORKFLOW_REMIND).build();
    }

    //声明队列（自研网关流程节点处理事项）
    @Bean("queueForGatewayWorkflowRemind")
    public Queue queueForGatewayWorkflowRemind() {
        //获取默认死信队列默认参数，【重要】 OA建立的通知队列，不包括死信队列
//        Map<String, Object> args = this.getDefaultDeadQueueArgs();
        return QueueBuilder.durable(RabbitExcQueConstant.AMPRODUCT_QUEUE_GATEWAY_FLOW_REMIND).build();
    }

    //声明队列（OA流程同步）
    @Bean("queueForGatewayWorkflowOaMobileAudit")
    public Queue queueForGatewayWorkflowOaMobileAudit() {
        return QueueBuilder.durable(RabbitExcQueConstant.GATEWAY_QUEUE_FLOW_OA_MOBILE_AUDIT).build();
    }

    //声明队列（OA流程同步）
    @Bean("queueForGatewayWorkflowCmdb")
    public Queue queueForGatewayWorkflowCmdb() {
        return QueueBuilder.durable(RabbitExcQueConstant.GATEWAY_QUEUE_FLOW_CMDB).build();
    }

    //声明队列（it流程设备变更）
    @Bean("queueForGatewayWorkflowItflow")
    public Queue queueForGatewayWorkflowItflow() {
        return QueueBuilder.durable(RabbitExcQueConstant.GATEWAY_QUEUE_FLOW_EQUIPMENT_MODIFY).build();
    }

    //声明队列（批量上传附件至OA档案系统通知队列）
    @Bean("queueForBatchUpload")
    public Queue queueForBatchUpload() {
        //获取默认死信队列默认参数，【重要】 OA建立的通知队列，不包括死信队列
//        Map<String, Object> args = this.getDefaultDeadQueueArgs();
        return QueueBuilder.durable(RabbitExcQueConstant.AMPRODUCT_QUEUE_BATCH_UPLOAD).build();
    }

    //声明队列（批量同步产品中心信息披露审核事件通知队列）
    @Bean("queueForSyncProdCenterDisclosureRecord")
    public Queue queueForSyncProdCenterDisclosureRecord() {
        //获取默认死信队列默认参数，【重要】 OA建立的通知队列，不包括死信队列
//        Map<String, Object> args = this.getDefaultDeadQueueArgs();
        return QueueBuilder.durable(RabbitExcQueConstant.AMPRODUCT_QUEUE_SYNC_PROD_CENTER_DISCLOSURE_RECORD).build();
    }

    //声明队列（批量上传附件至OA档案系统通知队列）
    @Bean("queueForOpenDayRuleRemind")
    public Queue queueForOpenDayRuleRemind() {
        //获取默认死信队列默认参数，【重要】 OA建立的通知队列，不包括死信队列
//        Map<String, Object> args = this.getDefaultDeadQueueArgs();
        return QueueBuilder.durable(RabbitExcQueConstant.AMPRODUCT_QUEUE_OPENDAYRULE_RIMIND).build();
    }

    //声明队列（批量上传附件至OA档案系统通知队列）
    @Bean("queueForProdCreateSync")
    public Queue queueForProdCreateSync() {
        //获取默认死信队列默认参数，【重要】 OA建立的通知队列，不包括死信队列
//        Map<String, Object> args = this.getDefaultDeadQueueArgs();
        return QueueBuilder.durable(RabbitExcQueConstant.AMPRODUCT_QUEUE_PROD_CREATE_SYNC).build();
    }

    //声明队列（信息披露自动同步至产品中心）
    @Bean("queueForDisclosureRecord")
    public Queue queueForDisclosureRecord() {
        //获取默认死信队列默认参数，【重要】 OA建立的通知队列，不包括死信队列
//        Map<String, Object> args = this.getDefaultDeadQueueArgs();
        return QueueBuilder.durable(RabbitExcQueConstant.AMPRODUCT_QUEUE_DISCLOSURE_RECORD).build();
    }

    //声明队列（信息披露事件自动触发）
    @Bean("queueForDisclosureRecordCreate")
    public Queue queueForDisclosureRecordCreate() {
        //获取默认死信队列默认参数，【重要】 OA建立的通知队列，不包括死信队列
//        Map<String, Object> args = this.getDefaultDeadQueueArgs();
        return QueueBuilder.durable(RabbitExcQueConstant.AMPRODUCT_QUEUE_DISCLOSURE_RECORD_CREATE).build();
    }

    //声明队列（flowable流程消息）
    @Bean("queueForFlowableMsg")
    public Queue queueForFlowableMsg() {
        return QueueBuilder.durable(RabbitExcQueConstant.GATEWAY_QUEUE_EASY_FLOW_MSG).build();
    }
    //End of 队列声明---------------------------------------------------------


    //队列、交换机绑定---------------------------------------------------------
    //绑定死信队列和交换机
    @Bean
    public Binding queueExchangeBindForDead(@Qualifier("queueForDead") Queue queueForDead,
                                            @Qualifier("exchangeDead") TopicExchange exchangeDead) {
        return BindingBuilder.bind(queueForDead).to(exchangeDead).with(RabbitExcQueConstant.AMPRODUCT_ROUTINGKEY_DEAD);
    }


    //绑定队列和交换机，根据路由键模糊匹配（短信邮件消息）
    @Bean
    public Binding queueExchangeBindForMessage(@Qualifier("queueForMessage") Queue queue,
                                               @Qualifier("exchangeDefault") TopicExchange defaultExchange) {
        return BindingBuilder.bind(queue).to(defaultExchange).with(RabbitExcQueConstant.AMPRODUCT_KEY_MESSAGE);
    }

    //绑定队列和交换机，根据路由键模糊匹配（异步任务）
    @Bean
    public Binding queueExchangeBindForTask(@Qualifier("queueForTask") Queue queue,
                                            @Qualifier("exchangeDefault") TopicExchange defaultExchange) {
        return BindingBuilder.bind(queue).to(defaultExchange).with(RabbitExcQueConstant.AMPRODUCT_KEY_TASK);
    }

    //绑定队列和交换机，根据路由键模糊匹配（工作流程异步任务）
    @Bean
    public Binding queueExchangeBindForWorkFlow(@Qualifier("queueForWorkflow") Queue queue,
                                                @Qualifier("exchangeDefault") TopicExchange defaultExchange) {
        return BindingBuilder.bind(queue).to(defaultExchange).with(RabbitExcQueConstant.AMPRODUCT_KEY_WORKFLOW);
    }

    //绑定队列和交换机，根据路由键模糊匹配（OA流程流转）
    @Bean
    public Binding queueExchangeBindForBatchUpload(@Qualifier("queueForOaWorkflowRemind") Queue queue,
                                                   @Qualifier("exchangeDefault") TopicExchange defaultExchange) {
        return BindingBuilder.bind(queue).to(defaultExchange).with(RabbitExcQueConstant.AMPRODUCT_KEY_OA_WORKFLOW_REMIND);
    }

    //绑定队列和交换机，根据路由键模糊匹配（OA流程流转）
    @Bean
    public Binding queueExchangeBindForGatewayWorkFlowRemind(@Qualifier("queueForGatewayWorkflowRemind") Queue queue,
                                                             @Qualifier("exchangeDefault") TopicExchange defaultExchange) {
        return BindingBuilder.bind(queue).to(defaultExchange).with(RabbitExcQueConstant.AMPRODUCT_QUEUE_GATEWAY_FLOW_REMIND);
    }

    //绑定队列和交换机，根据路由键模糊匹配（OA流程流转）
    @Bean
    public Binding queueExchangeBindForSyncProdCenterDisclosureRecord(@Qualifier("queueForSyncProdCenterDisclosureRecord") Queue queue,
                                                                      @Qualifier("exchangeDefault") TopicExchange defaultExchange) {
        return BindingBuilder.bind(queue).to(defaultExchange).with(RabbitExcQueConstant.AMPRODUCT_KEY_SYNC_PROD_CENTER_DISCLOSURE_RECORD);
    }

    //绑定队列和交换机，根据路由键模糊匹配（OA流程流转）
    @Bean
    public Binding queueExchangeBindForSyncOaReviewStatus(@Qualifier("queueForBatchUpload") Queue queue,
                                                          @Qualifier("exchangeDefault") TopicExchange defaultExchange) {
        return BindingBuilder.bind(queue).to(defaultExchange).with(RabbitExcQueConstant.AMPRODUCT_KEY_BATCH_UPLOAD);
    }

    //绑定队列和交换机，根据路由键模糊匹配（OA流程流转）
    @Bean
    public Binding queueExchangeBindForOpenDayRuleRemind(@Qualifier("queueForOpenDayRuleRemind") Queue queue,
                                                         @Qualifier("exchangeDefault") TopicExchange defaultExchange) {
        return BindingBuilder.bind(queue).to(defaultExchange).with(RabbitExcQueConstant.AMPRODUCT_KEY_OPENDAYRULE_RIMIND);
    }

    //绑定队列和交换机，根据路由键模糊匹配（OA流程流转）
    @Bean
    public Binding queueExchangeBindForProdCreateSync(@Qualifier("queueForProdCreateSync") Queue queue,
                                                      @Qualifier("exchangeDefault") TopicExchange defaultExchange) {
        return BindingBuilder.bind(queue).to(defaultExchange).with(RabbitExcQueConstant.AMPRODUCT_KEY_PROD_CREATE_SYNC);
    }

    //绑定队列和交换机，根据路由键模糊匹配（信息披露自动同步至产品中心）
    @Bean
    public Binding queueExchangeBindForDisclosureRecord(@Qualifier("queueForDisclosureRecord") Queue queue,
                                                        @Qualifier("exchangeDefault") TopicExchange defaultExchange) {
        return BindingBuilder.bind(queue).to(defaultExchange).with(RabbitExcQueConstant.AMPRODUCT_KEY_DISCLOSURE_RECORD);
    }

    //绑定队列和交换机，根据路由键模糊匹配（信息披露事件自动触发）
    @Bean
    public Binding queueExchangeBindForDisclosureRecordCreate(@Qualifier("queueForDisclosureRecordCreate") Queue queue,
                                                              @Qualifier("exchangeDefault") TopicExchange defaultExchange) {
        return BindingBuilder.bind(queue).to(defaultExchange).with(RabbitExcQueConstant.AMPRODUCT_KEY_DISCLOSURE_RECORD_CREATE);
    }

    //绑定队列和交换机，根据路由键模糊匹配（OA流程同步）
    @Bean
    public Binding queueExchangeBindForGatewayWorkflowOaMobileAudit(@Qualifier("queueForGatewayWorkflowOaMobileAudit") Queue queue,
                                                                    @Qualifier("exchangeOaMobileAudit") DirectExchange exchangeOaMobileAudit) {
        return BindingBuilder.bind(queue).to(exchangeOaMobileAudit).with(RabbitExcQueConstant.GATEWAY_QUEUE_FLOW_OA_MOBILE_AUDIT);
    }
    @Bean
    public Binding queueExchangeBindForGatewayWorkflowCmdb(@Qualifier("queueForGatewayWorkflowCmdb") Queue queue,
                                                                    @Qualifier("exchangeCmdb") DirectExchange exchangeCmdb) {
        return BindingBuilder.bind(queue).to(exchangeCmdb).with(RabbitExcQueConstant.GATEWAY_QUEUE_FLOW_CMDB);
    }
    //绑定队列和交换机，根据路由键模糊匹配（it流程-设备变更）
    @Bean
    public Binding queueExchangeBindForGatewayWorkflowItflow(@Qualifier("queueForGatewayWorkflowItflow") Queue queue,
                                                                    @Qualifier("exchangeItflow") DirectExchange exchangeItflow) {
        return BindingBuilder.bind(queue).to(exchangeItflow).with(RabbitExcQueConstant.GATEWAY_QUEUE_FLOW_EQUIPMENT_MODIFY);
    }

    //绑定队列和交换机
    @Bean
    public Binding queueExchangeBindForFlowableMsg(@Qualifier("queueForFlowableMsg") Queue queue,
                                                             @Qualifier("exchangeFlowableMsg") DirectExchange exchangeFlowableMsg) {
        return BindingBuilder.bind(queue).to(exchangeFlowableMsg).with(RabbitExcQueConstant.GATEWAY_QUEUE_EASY_FLOW_MSG);
    }
    //End of 队列、交换机绑定---------------------------------------------------------

// 通过ACK确认机制，而不是事物机制确认信息发送与接收
//    /**
//     * 配置启用rabbitmq事务
//     * @param connectionFactory
//     * @return
//     */
//    @Bean
//    public RabbitTransactionManager rabbitTransactionManager(CachingConnectionFactory connectionFactory) {
//        return new RabbitTransactionManager(connectionFactory);
//    }


    /*
     * 获取死信队列绑定参数
     * */
    public Map getDefaultDeadQueueArgs() {
        Map<String, Object> args = new HashMap<>();
        //声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", RabbitExcQueConstant.AMPRODUCT_EXCHANGE_DEAD);
        //声明当前队列的死信路由key
        args.put("x-dead-letter-routing-key", RabbitExcQueConstant.AMPRODUCT_ROUTINGKEY_DEAD);
        return args;
    }


}
